package com.learn.algorithm;

public class Random {
    // 需求1: 给一个随机生成1-5之间的函数 写一个随机生成1-7之间的函数

    /**
     * 随机生成1-5之间的整数
     */
    public static int getRandom1_5() {
        return (int) (Math.random() * 5) + 1;
    }

    /**
     * 根据随机生成1-5的函数 得到了随机生成0-1的函数
     */
    public static int getRandom1_0() {
        int result;
        do {
            result = getRandom1_5();
        } while (result == 3);
        return result < 3 ? 0 : 1;
    }

    /**
     * 根据随机生成的0-1 得到随机生成的三位二进制数000-110
     * 再加1即得到随机生成的1-7之间的数
     */
    public static int getRandom1_7() {
        int result;
        do {
            result = (getRandom1_0() << 2) + (getRandom1_0() << 1) + getRandom1_0();
        } while (result == 7);
        return result + 1;
    }

    public static void verifyRandom1_7() {
        int[] counts = new int[8];
        for (int i = 0; i < 100000000; i++) {
            int random = getRandom1_7();
            counts[random]++;
        }
        for (int count : counts) {
            System.out.println(count);
        }
    }

    // 需求2: 已知函数p以概率p返回0 以概率1-p返回1 p != 1 - p
    //       使用函数p以相等的概率返回0 1
    public static int p() {
        return Math.random() < 0.3 ? 0 : 1;
    }

    // 连续调用2次p() 如果两次的值不同 即两次分别生成0 1或1 0 则将第一次生成的值返回
    // 即可得到相同概率生成的0 1
    public static int p0_1() {
        int result;
        do {
            result = p();
        } while (result == p());
        return result;
    }

    public static void verifyRandom1_0() {
        int[] counts = new int[2];
        for (int i = 0; i < 100000000; i++) {
            int random = p0_1();
            counts[random]++;
        }
        for (int count : counts) {
            System.out.println(count);
        }
    }

    public static void main(String[] args) {
        verifyRandom1_7();
        verifyRandom1_0();
    }
}
